Summary
Exchange Online remediation with Powershell. Module install requires admin access or setting Scope to CurrentUser.
Note
Note carefully the date formatting - US date formatting is in use even for tenants/locations not in US.
Commands
Powershell Setup
PowerShell:
Install Exo Management: Admin:
Install-Module -Name ExchangeOnlineManagement
Y Y
Connect:
Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -ShowProgress $true -UserPrincipalName [email protected]
authentication dialog with MFA will appear
Connect to Security & Compliance Center PowerShell:
PS > Connect-IPPSSession -UserPrincipalName [email protected] Removed the PSSession ExchangeOnlineInternalSession_1 connected to outlook.office365.com WARNING: Your connection has been redirected to the following URI: "https://aus01b.ps.compliance.protection.outlook.com/Powershell-LiveId?BasicAuthToOAuthConversion=true&HideBannerMessage=true;PSVersion=5.1.19041.1"
Search: PS > $Search=New-ComplianceSearch -Name "2303_01" -ExchangeLocation All -ContentMatchQuery '(Received:9/6/2022..9/15/2022) AND (From:[email protected]) AND (Subject:"Project Documents")'
New-ComplianceSearch -Name "Phish_GL_0920" -ExchangeLocation All -ContentMatchQuery '(Received:8/14/2022..9/14/2022) AND (From:[email protected])'
or '(Received:8/14/2022..9/14/2022) AND "keyword"'
PS > Start-ComplianceSearch -Identity "Remove Phishing Message"
Status: PS > Get-ComplianceSearch -Identity "Remove Phishing Message"
Long form: PS > Get-ComplianceSearch -Identity "Remove Phishing Message" | Format-List *
Too long? add | out-host -paging
Permissions: O365 Security, Permissions, eDiscovery Manager, eDiscovery Admin, add self
Preview: PS > New-ComplianceSearchAction -SearchName "Remove Phishing Message" -Preview
Status on preview: PS > Get-ComplianceSearchAction "Remove Phishing Message_Preview"
Get the preview: PS > (Get-ComplianceSearchAction "Remove Phishing Message_Preview" | Select-Object -ExpandProperty Results) -split ","
Extract: New-ComplianceSearchAction -SearchName "Remove Phishing Message" -Export -Format FxStream -SharePointArchiveFormat SingleZip -ExchangeArchiveFormat SinglePst
Download via Edge. Must set it up with: edge://flags/#edge-click-once
If the existing value is set to Default or Disabled in the dropdown list, change it to Enabled.
Delete (Recycle Bin):
PS > New-ComplianceSearchAction -SearchName "Remove Phishing Message" -Purge -PurgeType SoftDelete
or Delete outright:
PS > New-ComplianceSearchAction -SearchName "Remove Phishing Message" -Purge -PurgeType HardDelete
Status:
PS > Get-ComplianceSearchAction "Remove Phishing Message_Purge"
Long form:
PS > Get-ComplianceSearchAction "Remove Phishing Message_Purge" | Format-List
Disconnect:
PS > Disconnect-ExchangeOnline
Running this cmdlet clears all active sessions created using Connect-ExchangeOnline
or Connect-IPPSSession
.
Press(Y/y/A/a) if you want to continue.
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"):
Removed the PSSession ExchangeOnlineInternalSession_5 connected to aus01b.ps.compliance.protection.outlook.com
Disconnected successfully !
Recovering Purged Items (Undelete)
NOTE Need permissions set up in EXO Permissions + "Mailbox Import Export ", Role: Mailbox Import Export, Member:self
Check recovery possible (SingleItemRecovery must be enabled):
Get-Mailbox "Bob Example" | Format-List SingleItemRecoveryEnabled,RetainDeletedItemsFor
SingleItemRecoveryEnabled : True
RetainDeletedItemsFor : 14.00:00:00
Folder checks:
Get-MailboxFolderStatistics "[email protected]" -FolderScope RecoverableItems | FL Name,FolderAndSubfolderSize,ItemsInFolderAndSubfolders
- shows all recoverable item folders (deleted, purged, etc).
Search by subject:
Get-RecoverableItems -Identity [email protected] -SubjectContains "FY Accounting" -FilterItemType IPM.Note -FilterStartTime "2/11/2022 12:00:00 AM" -FilterEndTime "2/10/2022 11:59:59 PM"
- returns all of the available recoverable deleted messages with the specified subject in the mailbox [email protected] for the specified date/time range, USA date format. "IPM.Note" is the email item type.
Purged item full list:
Get-RecoverableItems -Identity "[email protected]" -SourceFolder PurgedItems
- all purged items. Of importance here is Folder ID as that's needed for restoring items deleted from that folder or filtering.
Shorter variant with restrictions to only show modified time, subject, message type, and last location (limiting to 4 columns seems to be ideal)
Get-RecoverableItems -Identity "[email protected]" -SourceFolder PurgedItems | select lastmodifiedtime, subject, itemclass, LastParentPath
One-folder list:
Get-RecoverableItems -Identity "[email protected]" -SourceFolder PurgedItems -LastParentFolderID <folderid>
One-folder recovery:
Get-RecoverableItems -Identity "[email protected]" -SourceFolder PurgedItems -LastParentFolderID <folderid> | Restore-RecoverableItems
Recover into Export
You can use compliance search to recover deleted/purged items. Need to specify those folders as the target. That requires knowing the folder IDs (per user)
Folder IDs:
$mbx="[email protected]"
$mbxStatistics = Get-MailboxFolderStatistics -Identity $mbx
$folderQueries = @()
foreach ($stat in $mbxStatistics){
$folderName = $stat.Name
$folderId = $stat.FolderId;
$folderPath = $stat.FolderPath;
$encoding = [System.Text.Encoding]::GetEncoding("us-ascii")
$nibbler = $encoding.GetBytes("0123456789ABCDEF");
$folderIdBytes = [Convert]::FromBase64String($folderId);
$indexIdBytes = New-Object byte[] 48;
$indexIdIdx = 0;
$folderIdBytes | select -Skip 23 -First 24 | %{$indexIdBytes[$indexIdIdx++] = $nibbler[$_ -shr 4]; $indexIdBytes[$indexIdIdx++] = $nibbler[$_ -band 0xF]}
$folderIdConverted = $($encoding.GetString($indexIdBytes))
$folderDetails = New-Object PSObject
Add-Member -InputObject $folderDetails -MemberType NoteProperty -Name FolderName -Value $folderName
Add-Member -InputObject $folderDetails -MemberType NoteProperty -Name FolderId -Value $folderIdConverted
Add-Member -InputObject $folderDetails -MemberType NoteProperty -Name FolderPath -Value $FolderPath
$folderQueries += $folderDetails
}
$folderQueries
The above will return all folder IDs. Note the /Deleted Items, /Deletions, and /Purges (that's deleted, and deleted from deleted (user recoverable), and purged (admin recoverable))
Then search
New-ComplianceSearch -Name "MySearch" -ExchangeLocation All -ContentMatchQuery 'folderid:1000000000000000000000000000000000000000010A0000 OR folderid:100000000000000000000000000000000000000001180000 OR folderid:1000000000000000000000000000000000000000011A0000'
Then export:
New-ComplianceSearchAction -SearchName "MySearch" -Export -Format FxStream -SharePointArchiveFormat SingleZip -ExchangeArchiveFormat SinglePst
Message Trace
All sender IPs for sender:
Get-MessageTrace -SenderAddress [email protected] -StartDate 10/24/2022 -EndDate 11/03/2022 | select fromip | Sort-Object fromip | Get-Unique -asstring
messages for IP:
Get-MessageTrace -SenderAddress [email protected] -StartDate 10/24/2022 -EndDate 11/03/2022 -FromIP 10.1.1.1